package com.gopay.bis.manager.bank.bcdl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.gopay.common.domain.bank.boc.bcdl.queryTrans.req.*;
import com.gopay.common.domain.bank.boc.bcdl.queryTrans.res.TransResQueryB2e0035Body;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.domain.bank.BcdlMessage;
import com.gopay.common.domain.bank.boc.bcdl.BaseHead;
import com.gopay.common.domain.bank.boc.bcdl.BaseReqBody;
import com.gopay.common.domain.bank.boc.bcdl.Trans;
import com.gopay.common.domain.bank.boc.bcdl.batch.req.ReqBatchDrawee;
import com.gopay.common.domain.bank.boc.bcdl.batch.req.ReqBatchParam;
import com.gopay.common.domain.bank.boc.bcdl.batch.req.ReqBatchPayee;
import com.gopay.common.domain.bank.boc.bcdl.batch.req.TransReqBatch;
import com.gopay.common.domain.bank.boc.bcdl.batch.res.TransResBatchBody;
import com.gopay.common.domain.bank.boc.bcdl.corp.req.ReqCorpDrawee;
import com.gopay.common.domain.bank.boc.bcdl.corp.req.ReqCorpParam;
import com.gopay.common.domain.bank.boc.bcdl.corp.req.ReqCorpPayee;
import com.gopay.common.domain.bank.boc.bcdl.corp.req.TransReqCorp;
import com.gopay.common.domain.bank.boc.bcdl.corp.res.TransResCorpBody;
import com.gopay.common.domain.bank.boc.bcdl.interbank.req.ReqInterBankDrawee;
import com.gopay.common.domain.bank.boc.bcdl.interbank.req.ReqInterBankDraweeAcc;
import com.gopay.common.domain.bank.boc.bcdl.interbank.req.ReqInterBankParam;
import com.gopay.common.domain.bank.boc.bcdl.interbank.req.ReqInterBankPayee;
import com.gopay.common.domain.bank.boc.bcdl.interbank.req.TransReqInterBank;
import com.gopay.common.domain.bank.boc.bcdl.interbank.res.TransResInterBankBody;
import com.gopay.common.domain.bank.boc.bcdl.person.req.ReqPersonDrawee;
import com.gopay.common.domain.bank.boc.bcdl.person.req.ReqPersonParam;
import com.gopay.common.domain.bank.boc.bcdl.person.req.ReqPersonPayee;
import com.gopay.common.domain.bank.boc.bcdl.person.req.TransReqPerson;
import com.gopay.common.domain.bank.boc.bcdl.query.req.ReqQuery;
import com.gopay.common.domain.bank.boc.bcdl.query.req.TransReqQuery;
import com.gopay.common.domain.bank.boc.bcdl.query.res.TransResQueryBody;
import com.gopay.common.domain.bank.boc.bcdl.querybalance.req.ReqQueryBalAccount;
import com.gopay.common.domain.bank.boc.bcdl.querybalance.req.TransReqQueryBalance;
import com.gopay.common.domain.bank.boc.bcdl.querybalance.res.TransResQueryBalanceBody;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.DateUtils;
import com.gopay.remote.bank.businesses.BcdlService;

/**
 * @author lianpeng
 *	中行银企直连拼装对象
 */
public class BocBcdlManager {
	@Resource(name = "bocBcdlService")
	private BcdlService bocBcdlService;
	
	@Resource(name = "bocConfig")
	private Map<String, String> bocConfig;
	
	public TransResInterBankBody payInterBank(BcdlMessage message) throws GopayException{
		BaseReqBody body = convertInterBank(message);
		BankLogUtils.printBcdlEftManagerSendLog(body);
		TransResInterBankBody result = (TransResInterBankBody) bocBcdlService.eft(body);
		BankLogUtils.printBcdlEftManagerReturnLog(result);
		return result;
	}
	
	public TransResCorpBody payCorp(BcdlMessage message) throws GopayException{
		// 构建对公对象
		BaseReqBody body = convertCorp(message);
		BankLogUtils.printBcdlEftManagerSendLog(body);
		// 发送银行请求
		TransResCorpBody result = (TransResCorpBody) bocBcdlService.eft(body);
		BankLogUtils.printBcdlEftManagerReturnLog(result);
		return result;
	}
	
	public TransResBatchBody payPerson(BcdlMessage message) throws GopayException{
		// 构建对私对象
//		BaseReqBody body = convertPerson(message);
		//因对私转账限额太低，使用快捷代发业务
		BaseReqBody body = convertBatch(message);
		BankLogUtils.printBcdlEftManagerSendLog(body);
		// 发送银行请求
		TransResBatchBody result = (TransResBatchBody) bocBcdlService.eft(body);
		BankLogUtils.printBcdlEftManagerReturnLog(result);
		return result;
	}
	
	public TransResQueryBody payQuery(BcdlMessage message) throws GopayException{
		// 构建查询对象
		BaseReqBody body = convertQuery(message);
		BankLogUtils.printBcdlManagerQuerySendLog(body);
		// 发送银行
		TransResQueryBody result = (TransResQueryBody) bocBcdlService.query(body);
		BankLogUtils.printBcdlEftManagerReturnLog(result);
		return result;
	}
	
	public TransResQueryBalanceBody queryBal(BcdlMessage message) throws GopayException{
		// 构建查询对象
		BaseReqBody body = convertQueryBal(message);
		BankLogUtils.printBcdlManagerQuerySendLog(body);
		// 发送银行
		TransResQueryBalanceBody result = (TransResQueryBalanceBody) bocBcdlService.queryBalance(body);
		BankLogUtils.printBcdlEftManagerReturnLog(result);
		result.setPayAccNum(bocConfig.get("BOC.BCDL.PAY.ACCOUNTNO"));
		return result;
	}

	private BaseReqBody convertQueryBal(BcdlMessage message) {
		// TODO Auto-generated method stub
		List<ReqQueryBalAccount> list = new ArrayList<ReqQueryBalAccount>();
		ReqQueryBalAccount account = new ReqQueryBalAccount();
		account.setActacn(bocConfig.get("BOC.BCDL.PAY.ACCOUNTNO"));
		account.setIbknum(bocConfig.get("BOC.BCDL.PAY.IBKNUM"));
		list.add(account);
		BaseReqBody req = buildReq(new TransReqQueryBalance(list), message);
		return req;
	}

	private BaseReqBody convertQuery(BcdlMessage message) {
		// TODO Auto-generated method stub
		List<ReqQuery> list = new ArrayList<ReqQuery>();
		ReqQuery query = new ReqQuery();
		query.setInsid(message.getOrderId());
		query.setObssid("");
		list.add(query);
		BaseReqBody req = buildReq(new TransReqQuery(list), message);
		return req;
	}


	/**
	 * 查询网银明细
	 *
	 * @param
	 * @return
	 * @throws GopayException
	 */
	public TransResQueryB2e0035Body queryAcctDetail(BcdlMessage message) throws GopayException{
		BaseReqBody body = converTransB2e0035(message);
		BankLogUtils.printBcdlEftManagerSendLog(body);
		TransResQueryB2e0035Body retbody=(TransResQueryB2e0035Body)bocBcdlService.queryAcctDetail(body);
		return retbody;
	}


	private BaseReqBody converTransB2e0035(BcdlMessage message) {
		TransB2e0035Req req=new TransB2e0035Req();
		B2e0035Req b2ereq=new B2e0035Req();
		b2ereq.setIbknum(bocConfig.get("BOC.BCDL.PAY.IBKNUM"));
		b2ereq.setActacn(bocConfig.get("BOC.BCDL.PAY.ACCOUNTNO"));
		// 查询类型非空数码  4 位非空枚举：2001（当日查询）2002（历史 查询） 2005 （T+1查询 T日夜间批量交易
		b2ereq.setType(String.valueOf(message.getTradeType()));
		DatescopeReq socpereq=new DatescopeReq();
		//查询类型为2002，日期为当前日期之前一年内,跨度为一个自然月；2001,系统 默认取当前 日期；如果查询类型是	2005，系统默认取当前日期前一天
		//YYYYMMDD 开始日期
		socpereq.setFrom(message.getOrderDate());
		//结束日期
		socpereq.setTo(message.getOrderDate());
		b2ereq.setDatescopeReq(socpereq);
		AmountscopeReq amountscopeReq=new AmountscopeReq();
		//下限(含) 可空正数数	字, 长度（22，2）	1、可空正 数数字, 长度（18，2）2、为空时，系统默认0.00
		amountscopeReq.setFrom("");
		//上限（含）可空正数数	字, 长度（22，2） 1、可空正数数字, 长度（18，2）	2、大于金额下限，为空时，系统默认为	99999999999	9999999.99
		amountscopeReq.setTo("");
		b2ereq.setAmountscope(amountscopeReq);
       //本次查询的交易起始位	置可空数码最长8位,第一次查询以1开始；如果该项	为空则默认为1
		b2ereq.setBegnum(String.valueOf(message.getDcblType()));
		//查询记录数可空数码	2位，不足2位前面补0最大50，如果该项为空		则默认为	1。不足2位，前补0
		b2ereq.setRecnum("50");
       //来往账标 0-全部，1-来账，2-往账,3-内部往来，4-外部交易，5 部分内部往来其中3、4、5只有现金3.0客户可以	上送
		b2ereq.setDirection("0");
		req.setB2e0035Req(b2ereq);
		BaseReqBody reqbody = buildReq(req, message);
		return reqbody;
	}
	
	private BaseReqBody convertInterBank(BcdlMessage message) {
		// TODO Auto-generated method stub
		List<ReqInterBankParam> params = new ArrayList<ReqInterBankParam>();
		ReqInterBankParam param = new ReqInterBankParam();
		param.setInsid(message.getOrderId());
		param.setTrnamt(message.getAmount().toString());
		param.setTrncur(bocConfig.get("BOC.BCDL.CUR"));
		String urgencyFlag = 0==message.getEmergency()?"1":"0";
		param.setPriolv(urgencyFlag);//银行处理优先级 0普通 1.加急
		param.setFurinfo(message.getOrderId());
		
		ReqInterBankDrawee fractn = new ReqInterBankDrawee();
		fractn.setActacn(bocConfig.get("BOC.BCDL.PAY.ACCOUNTNO"));
		fractn.setActnam(bocConfig.get("BOC.BCDL.PAY.ACCOUNTNAME"));
		fractn.setFribkn(bocConfig.get("BOC.BCDL.PAY.IBKNUM"));
		param.setFractn(fractn);
		
		ReqInterBankPayee toactn = new ReqInterBankPayee();
		toactn.setActacn(message.getRecvBankAcctNum());
		toactn.setToibkn(message.getPobcBankCode());
		toactn.setToname(message.getRecvBankAcctName());
		toactn.setType("04");
		param.setToactn(toactn);
		
		ReqInterBankDraweeAcc feeinfo = new ReqInterBankDraweeAcc();
		feeinfo.setActacn(bocConfig.get("BOC.BCDL.PAY.ACCOUNTNO"));
		feeinfo.setIbknum(bocConfig.get("BOC.BCDL.PAY.IBKNUM"));
		param.setFeeinfo(feeinfo);
		
		params.add(param);
		
		BaseReqBody req = buildReq(new TransReqInterBank(params), message);
		return req;
	}
	
	private BaseReqBody convertBatch(BcdlMessage message){
		List<ReqBatchParam> params = new ArrayList<ReqBatchParam>();
		ReqBatchParam param = new ReqBatchParam();
		param.setInsid(message.getOrderId());
		param.setPybcur(bocConfig.get("BOC.BCDL.CUR"));
		param.setPybamt(message.getAmount().toString());
		param.setPybnum("1");//批次数
		param.setCrdtyp("7");//6:他行，7:我行
		param.setFurinfo("EH");//EH:代付
		param.setUseinf(message.getOrderId());
		param.setTrfdate(DateUtils.getCurrDate("yyyyMMdd"));
		ReqBatchDrawee fractn = new ReqBatchDrawee();
		param.setFractn(fractn);
		fractn.setActacn(bocConfig.get("BOC.BCDL.PAY.ACCOUNTNO"));
		fractn.setActnam(bocConfig.get("BOC.BCDL.PAY.ACCOUNTNAME"));
		fractn.setFribkn(bocConfig.get("BOC.BCDL.PAY.IBKNUM"));
		List<ReqBatchPayee> detail = new ArrayList<ReqBatchPayee>();
		ReqBatchPayee payee = new ReqBatchPayee(); 
		detail.add(payee);
		payee.setToibkn("10");//10:默认值中行总行
		payee.setTobank(message.getPbocBankName());
		payee.setToactn(message.getRecvBankAcctNum());
		payee.setPydcur(bocConfig.get("BOC.BCDL.CUR"));
		payee.setPydamt(message.getAmount().toString());
		payee.setToname(message.getRecvBankAcctName());
		payee.setToidtp("");
		payee.setToidet("");
		payee.setFurinfo("");
		payee.setPurpose("");
		payee.setReserve1("");
		payee.setReserve2("");
		payee.setReserve3("");
		payee.setReserve4("");
		param.setDetail(detail);
		params.add(param);
		BaseReqBody req = buildReq(new TransReqBatch(null, params), message);
		req.setDcblType(BankConstants.DCBL_PERSON);
		return req;
	}

	private BaseReqBody convertPerson(BcdlMessage message) {
		// TODO Auto-generated method stub
		List<ReqPersonParam> params = new ArrayList<ReqPersonParam>();
		ReqPersonParam param = new ReqPersonParam();
		param.setInsid(message.getOrderId());
		param.setTrnamt(message.getAmount().toString());
		param.setTrncur(bocConfig.get("BOC.BCDL.CUR"));
		String urgencyFlag = 0==message.getEmergency()?"1":"0";
		param.setPriolv(urgencyFlag);//银行处理优先级 0普通 1.加急
		param.setCuspriolv(urgencyFlag);//客户处理优先级 0普通 1.加急
		param.setFurinfo(message.getOrderId());
		param.setTrfdate(DateUtils.getCurrDate("yyyyMMdd"));
		param.setComacn("");//手续费账号 如果为空,则使用付款账户代替。
		//param.setBocflag(0==message.getSysIOFlg()?"0":"1");//收款人是否中行账号 0:他行 1:中行
		param.setBocflag("1");
		ReqPersonDrawee fractn = new ReqPersonDrawee();
		param.setFractn(fractn);
		fractn.setActacn(bocConfig.get("BOC.BCDL.PAY.ACCOUNTNO"));
		fractn.setActnam(bocConfig.get("BOC.BCDL.PAY.ACCOUNTNAME"));
		fractn.setFribkn(bocConfig.get("BOC.BCDL.PAY.IBKNUM"));
		
		ReqPersonPayee toactn = new ReqPersonPayee();
		toactn.setActacn(message.getRecvBankAcctNum());
		toactn.setActtyp("");//可空,如果为空时默认为借记卡 此字段可以上送,但是无效,不对其进行业务校验
		toactn.setToaddr("");
		toactn.setTobknm(message.getPbocBankName());
		//toactn.setToibkn(message.getPobcBankCode()==null?"":message.getPobcBankCode());
		toactn.setToibkn("");
		toactn.setToname(message.getRecvBankAcctName());
		param.setToactn(toactn);
		
		params.add(param);
		BaseReqBody req = buildReq(new TransReqPerson(null, params), message);
		req.setDcblType(BankConstants.DCBL_PERSON);
		return req;
	}

	private BaseReqBody convertCorp(BcdlMessage message) {
		// TODO Auto-generated method stub
		List<ReqCorpParam> params = new ArrayList<ReqCorpParam>();
		ReqCorpParam param = new ReqCorpParam();
		param.setInsid(message.getOrderId());
		param.setTrnamt(message.getAmount().toString());
		param.setTrncur(bocConfig.get("BOC.BCDL.CUR"));
		String urgencyFlag = 0==message.getEmergency()?"1":"0";
		param.setPriolv(urgencyFlag);//是否加急 0普通 1.加急 
		param.setFurinfo(message.getOrderId());
		param.setTrfdate(DateUtils.getCurrDate("yyyyMMdd"));
		param.setComacn("");//手续费账号 如果为空,则使用付款账户代替。
		
		ReqCorpDrawee drawee = new ReqCorpDrawee();
		drawee.setActacn(bocConfig.get("BOC.BCDL.PAY.ACCOUNTNO"));
		drawee.setActnam(bocConfig.get("BOC.BCDL.PAY.ACCOUNTNAME"));
		drawee.setFribkn(bocConfig.get("BOC.BCDL.PAY.IBKNUM"));//付款人联行号，可空
		param.setFractn(drawee);
		
		ReqCorpPayee payee = new ReqCorpPayee();
		payee.setActacn(message.getRecvBankAcctNum());
		payee.setToaddr("");
		payee.setTobknm(message.getPbocBankName());
//		payee.setToibkn(message.getPobcBankCode());
		payee.setToname(message.getRecvBankAcctName());
		param.setToactn(payee);
		params.add(param);
		BaseReqBody req = buildReq(new TransReqCorp(null, params), message);
		req.setDcblType(BankConstants.DCBL_CORP);
		return req;
	}
	
	private BaseReqBody buildReq(Trans tran, BcdlMessage message){
		BaseReqBody req = new BaseReqBody();
//		BeanUtils.copyProperties(message, req);
		BaseHead head = new BaseHead();
		head.setTermid("");
		head.setTrnid(DateUtils.format(new Date(), "yyMMddHHmmss"));
		head.setCustid(bocConfig.get("BOC.BCDL.CUSTID"));
		head.setCusopr(bocConfig.get("BOC.BCDL.CUSOPR"));
		head.setOprpwd(bocConfig.get("BOC.BCDL.OPRPWD"));
		head.setUrl(bocConfig.get("BOC.BCDL.URL"));
		req.setHead(head);
		List<Trans> trans = new ArrayList<Trans>();
		trans.add(tran);
		req.setTrans(trans);
		// add by wjq 2017-12-28 记录日志需要获取订单号
		req.setOrderId(message.getOrderId());
		req.setOutOrderId(message.getOutOrderId());
		return req;
	}



}
